package cn.xinfei.xdecision.common.service.datax.midoffice;


import cn.xinfei.xdecision.common.model.datax.enums.MidOfficeCallEnum;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataException;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataExceptionType;
import cn.xinfei.xdecision.common.service.datax.midoffice.dto.ActiveCreditStartReqDTO;
import cn.xinfei.xdecision.common.service.datax.midoffice.dto.MidOfficeReqDTO;
import cn.xinfei.xdecision.common.service.sequence.SequenceSystem;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.Duration;


@Component
@Slf4j
public class MidOfficeSystem {
    @Resource
    private MidOfficeProperties midOfficeProperties;

    private static RestTemplate restTemplate = null;

    @Value("${xdecision.data.midoffice.connect_timeout:4000}")
    private int connectTimeout;

    @Value("${xdecision.data.midoffice.read_timeout:4000}")
    private int readTimeout;

    @PostConstruct
    public void init() {
        restTemplate = new RestTemplateBuilder()
                .setConnectTimeout(Duration.ofSeconds(connectTimeout))
                .setReadTimeout(Duration.ofSeconds(readTimeout))
                .build();
    }

    /**
     * 人行征信调起通知
     */
    public JSONObject activeCreditStartNotify(ActiveCreditStartReqDTO reqDTO) {
        MidOfficeReqDTO<ActiveCreditStartReqDTO> midOfficeReqDTO = new MidOfficeReqDTO<>();
        midOfficeReqDTO.setArgs(reqDTO);
        return postMidOffice(midOfficeReqDTO, MidOfficeCallEnum.ACTIVE_CREDIT_START_CALLBACK.getCode());
    }


    private JSONObject postMidOffice(MidOfficeReqDTO reqDto, String call) {
        reqDto.setUa(midOfficeProperties.getUa());
        String jsonParam = JSONObject.toJSONString(reqDto.getArgs());
        String sign = MidOfficeSignUtil.sign(midOfficeProperties.getUa(), midOfficeProperties.getKey(), call, jsonParam);
        reqDto.setSign(sign);
        try {
            HttpHeaders headers = new HttpHeaders();
            MediaType mediaType = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            headers.setContentType(mediaType);
            headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
            HttpEntity<String> reqEntity = new HttpEntity<>(JSONObject.toJSONString(reqDto), headers);
            ResponseEntity<String> res = restTemplate.postForEntity(midOfficeProperties.getBaseUrl() + call, reqEntity, String.class);
            JSONObject body = JSONObject.parseObject(res.getBody());
            if (res.getStatusCode().is2xxSuccessful() && body.getInteger("status") == 1) {
                log.info("中台回调成功,uri:{},请求报文:{},返回报文:{}", call, jsonParam, body);
                return body;
            } else {
                log.error("中台回调失败,uri:{}, 请求报文:{},返回报文:{}", call, jsonParam, res);
                throw new XDecisionDataException(
                        XDecisionDataExceptionType.CODE_REQUEST_MIDOFFICE_ERROR,
                        XDecisionDataExceptionType.CODE_REQUEST_MIDOFFICE_ERROR.text +
                                ",status=" + body.getString("status") + ",message=" + body.getString("message"));
            }
        } catch (Exception e) {
            throw new XDecisionDataException(XDecisionDataExceptionType.CODE_REQUEST_MIDOFFICE_ERROR, "请求中台回调接口异常", e);
        }
    }
}
